# import json
#
# from apscheduler.schedulers.blocking import BlockingScheduler
#
# from common.entitys.caiptal import TransCode2
# from common.entitys.monitor import MonitorType, Monitor
# from common.enums.Enums import FormCons
# from database.mapper.monitor_result import MonitorResult
# from service import training_model
# from utils.logger import Logger
# from utils import date_util, ave_util, price_util, msg_util, k_util_v1, form_util, \
#     macd_util_v1, cache_util
# from database.mapper import stock_monitor, monitor_result, user_info, stock_day_k
#
# frequency_config = 200  # 定时任务时间 单位秒
# logger = Logger('实时监控任务总').get_log()
#
#
# # 1.中材国际 2021-08-17买入操作复盘(1.房地产不景气2.阿富汗重建3.建筑装饰水泥建材)
#
# # 买入匹配
# # 1.是否为当前热点
# # 2.主力资金情况 (净流入):
# #     2.1.分歧情况
# #     2.2.主力资金和价格涨幅的分歧情况
# # 3.市盈率和业绩情况
# # 4.看下板块1234发力状态买
#
# # 开启监控定时任务
# def start_task():
#     # 先执行一次再开启定时任务 方便一次启动监控
#     monitor_task()
#     # 添加任务,时间间隔180S
#     scheduler = BlockingScheduler()
#     scheduler.add_job(monitor_task, 'interval', seconds=frequency_config, id='monitor_task')
#     scheduler.start()
#
#
# # 监控定时任务
# def monitor_task():
#     print("task_c执行时间" + date_util.get_date_time_str())
#     if route_task() == 0: return
#     sm_list = stock_monitor.select_distinct()
#     msg_dict = {}
#     for s_monitor in sm_list:
#         try:
#             monitor = Monitor(s_monitor.get('code'), s_monitor.get('name'))
#             monitor_one(monitor)
#             deal_msg(monitor, msg_dict)
#         except Exception as e:
#             logger.error('系统运行异常' + s_monitor.get('code') + s_monitor.get('name'))
#     send_msg(msg_dict)  # 发送用户消息提示
#
#
# # 以长城汽车为例写
# def monitor_one(monitor: Monitor):
#     rt_info = price_util.rt_info(monitor.code)  # 股票实时信息
#     monitor.rt_price = rt_info.get(TransCode2.price)  # 实时价格
#     monitor.cir_val = rt_info.get(TransCode2.ltsz)  # 流通市值
#     monitor.rt_flow.main_io = rt_info.get(TransCode2.main_io)  # 主力净流入
#     monitor.rt_flow.main_i = rt_info.get(TransCode2.main_i)
#     monitor.rt_flow.main_o = rt_info.get(TransCode2.main_o)
#     k_line = k_util_v1.day_k_size_rt(monitor.code, 16, monitor.rt_price)  # 获取最近的10日k线
#     monitor.last_max_price = k_line[1].get('max')  # 上一日最高价
#     monitor.last_min_price = k_line[1].get('min')  # 上一日最低价
#     monitor.last_sp_price = k_line[1].get('sp')  # 上一日收盘价
#     monitor.kp = k_line[0].get('kp')  # 开盘价
#     monitor.ave5 = ave_util.ave_line_price(k_line[0: 5], 5)  # 5日均线价格
#     monitor.ave10 = ave_util.ave_line_price(k_line[0: 10], 10)  # 10日均线价格
#     monitor.task_time = date_util.get_date_time_str()
#     monitor.rq = date_util.get_date_str()
#     macd_list3 = macd_util_v1.get_macd_rt(monitor.code, 3, monitor.rq, monitor.rt_price)
#     monitor.form_macd3 = form_util.thr_form(form_util.parse_x_reverse(macd_list3, 'macd'))  # macd数据形态
#     # 获取收盘价形态
#     get_best_form(monitor)
#     # 获取运行模式
#     get_train_info(monitor)
#     # 处理触发情况
#     deal_trigger(monitor)
#
#
# # 获取最佳形态
# def get_best_form(monitor: Monitor):
#     key = 'task_c_bask_form_' + monitor.code
#     best_form_info = cache_util.get_cache_expire(key)
#     if best_form_info is None:
#         k_line = stock_day_k.select_size(monitor.code, 15)
#         monitor.form_info = form_util.get_best_form(form_util.parse_x_reverse(k_line, 'sp'))
#         cache_util.set_cache_expire(key, json.dumps(monitor.form_info, default=lambda o: o.__dict__),
#                                     int((date_util.datetime2timestamp(
#                                         date_util.get_date_str() + ' 15:00:00') - date_util.get_timestamp_now()) / 60))
#     else:
#         monitor.form_info.__dict__ = eval(best_form_info)
#
#
# # 获取运行模式
# def get_train_info(monitor: Monitor):
#     cache_key = 'task_c' + monitor.code + 'train_info'
#     cache_train_info = cache_util.get_cache_expire(cache_key)
#     if cache_train_info is None:
#         train_info = training_model.train(monitor.code)
#         zf_price = round((train_info.get('end_price') - train_info.get('beg_price')) / train_info.get('beg_price'), 4)
#         zf_earn = round((train_info.get('champion_max') - 100000) / 100000, 4)
#         monitor.train_model.buy_ls = train_info.get('buy_ls')
#         monitor.train_model.sel_ls = train_info.get('sel_ls')
#         monitor.train_model.buy_jfg = train_info.get('buy_jfg')
#         monitor.train_model.sel_jfg = train_info.get('sel_jfg')
#         amt_sum_sort = train_info['amt_sum_sort'][0:10]
#         amt_sum_sort.reverse()
#         monitor.train_model.zf_earn_sort_m_io = amt_sum_sort
#
#         # 全持收益
#         monitor.train_model.zf_price_m_io = zf_price
#         monitor.train_model.zf_earn_m_io = zf_earn
#         monitor.train_model.best_module_m_io = train_info.get('champion_max_inv')
#         monitor.flow_sum_dict = train_info['flow_sum_dict']
#
#         cache_util.set_cache_expire(cache_key, {'best_module': train_info.get('champion_max_inv'),
#                                                 'flow_sum_dict': train_info['flow_sum_dict'],
#                                                 'zf_price_m_io': monitor.train_model.zf_price_m_io,
#                                                 'zf_earn_sort_m_io': monitor.train_model.zf_earn_sort_m_io,
#                                                 'buy_ls': monitor.train_model.buy_ls,
#                                                 'sel_ls': monitor.train_model.sel_ls,
#                                                 'buy_jfg': monitor.train_model.buy_jfg,
#                                                 'sel_jfg': monitor.train_model.sel_jfg,
#                                                 'zf_earn_m_io': monitor.train_model.zf_earn_m_io},
#                                     int((date_util.datetime2timestamp(
#                                         date_util.get_date_str() + ' 15:00:00') - date_util.get_timestamp_now()) / 60))
#     else:
#         monitor.train_model.best_module_m_io = cache_train_info.get('best_module')
#         monitor.train_model.zf_price_m_io = cache_train_info.get('zf_price_m_io')
#         monitor.train_model.zf_earn_m_io = cache_train_info.get('zf_earn_m_io')
#         monitor.train_model.zf_earn_sort_m_io = cache_train_info.get('zf_earn_sort_m_io')
#         monitor.flow_sum_dict = cache_train_info.get('flow_sum_dict')
#         monitor.train_model.buy_ls = cache_train_info.get('buy_ls')
#         monitor.train_model.sel_ls = cache_train_info.get('sel_ls')
#         monitor.train_model.buy_jfg = cache_train_info.get('buy_jfg')
#         monitor.train_model.sel_jfg = cache_train_info.get('sel_jfg')
#
#
# # 检查有效时间
# def route_task():
#     if not date_util.valid_day(date_util.get_date_str()):
#         return 0
#     date_time = date_util.get_date_time()
#     hour = date_time.hour
#     minute = date_time.minute
#     if 9 <= hour < 15 and not (hour == 9 and minute < 35) \
#             and not (hour == 11 and minute > 30) and not (hour == 12):
#         return 1
#     return 0
#
#
# # 处理触发
# # 数据一定要硬
# def deal_trigger(monitor: Monitor):
#     # 突破均线 处理
#     if ((monitor.form_info.best_form == FormCons.js and monitor.form_info.max_front > 70)
#         or (monitor.form_info.best_form == FormCons.sj and monitor.form_info.max_front < 66)
#         or monitor.form_info.best_form == FormCons.hj
#         or monitor.form_info.best_form == FormCons.j) \
#             and monitor.form_info.zf > 5 \
#             and monitor.form_info.max_score > 0.5:
#         if monitor.last_max_price < monitor.ave5 < monitor.rt_price:
#             monitor.break_ave5 = True
#             monitor.bs = 1
#             monitor.update_flag = True
#         if monitor.last_max_price < monitor.ave10 < monitor.rt_price:
#             monitor.break_ave10 = True
#             monitor.bs = 1
#             monitor.update_flag = True
#     # 跌破均线 处理
#     if ((monitor.form_info.best_form == FormCons.sj and monitor.form_info.max_front > 50)
#         or (monitor.form_info.best_form == FormCons.js and 30 < monitor.form_info.max_front < 70)
#         or monitor.form_info.best_form == FormCons.s
#         or monitor.form_info.best_form == FormCons.hs) \
#             and monitor.form_info.zf > 5 \
#             and monitor.form_info.max_score > 0.5 \
#             and (monitor.form_macd3 == '\\' or monitor.form_macd3 == '^'):
#         if monitor.last_min_price > monitor.ave5 > monitor.rt_price:
#             monitor.below_ave5 = True
#             monitor.bs = 2
#             monitor.update_flag = True
#         if monitor.last_min_price > monitor.ave10 > monitor.rt_price:
#             monitor.below_ave10 = True
#             monitor.bs = 2
#             monitor.update_flag = True
#
#     # 大资金 处理
#     if (monitor.train_model.zf_earn_m_io > 0
#         and monitor.train_model.zf_price_m_io > 0
#         and monitor.train_model.zf_earn_m_io / monitor.train_model.zf_price_m_io > 0.7) \
#             or (monitor.train_model.zf_earn_m_io < 0
#                 and monitor.train_model.zf_price_m_io < 0
#                 and monitor.train_model.zf_earn_m_io / monitor.train_model.zf_price_m_io < 0.4) \
#             or (monitor.train_model.zf_earn_m_io > 0
#                 and monitor.train_model.zf_price_m_io < 0):
#         buy_jfg = int(monitor.train_model.buy_jfg)
#         sel_jfg = int(monitor.train_model.sel_jfg)
#         # 资金离散度 计算稳定程度
#         if monitor.flow_sum_dict.get(buy_jfg) < 0 \
#                 and monitor.flow_sum_dict.get(buy_jfg - 1) + monitor.rt_flow.main_io > 1000000 \
#                 and monitor.flow_sum_dict.get(sel_jfg - 1) + monitor.rt_flow.main_io > 0 \
#                 and monitor.rt_flow.main_io > 1000000:  # 当天必须是流入的
#             monitor.main_io_buy = True
#             monitor.main_io_buy_model = str(buy_jfg) + ':' + str(sel_jfg)
#             monitor.bs = 1
#             monitor.update_flag = True
#         if monitor.flow_sum_dict.get(sel_jfg) > 0 \
#                 and monitor.flow_sum_dict.get(sel_jfg - 1) + monitor.rt_flow.main_io < -1000000 \
#                 and monitor.rt_flow.main_io < -1000000:
#             monitor.main_io_sell = True
#             monitor.main_io_sell_model = str(buy_jfg) + ':' + str(sel_jfg)
#             monitor.bs = 2
#             monitor.update_flag = True
#
#     # 资金和价格倒挂情况
#     if monitor.rt_price < monitor.last_sp_price and monitor.rt_flow.main_io > 1000000:
#         print(monitor.code + monitor.name + '资金和价格倒挂')
#         monitor.main_io_buy_model += '资金和价格倒挂'
#
#     # 数据库更新或者插入
#     if monitor.update_flag:
#         monitor_result_old = monitor_result.select_by_date_type(monitor.code, monitor.rq, MonitorType.four)
#         if monitor_result_old is not None:
#             old_mr = Monitor(monitor.code, monitor.name)
#             old_mr.__dict__ = eval(monitor_result_old.monitor_result.replace('false', 'False').replace('true', 'True'))
#             judge_prompt(old_mr, monitor)  # 比较差异
#         else:
#             monitor.prompt = True
#         if monitor.prompt:
#             monitor_result.up_or_in_by_code_rq(
#                 MonitorResult(monitor.code, monitor.rq, 'task_c', MonitorType.four,
#                               json.dumps(monitor, default=lambda o: o.__dict__), date_util.get_date_time()))
#
#
# # 比较两次变化
# def judge_prompt(old: Monitor, new: Monitor):
#     if (old.main_io_sell ^ new.main_io_sell) \
#             or (old.main_io_buy ^ new.main_io_buy) \
#             or ((old.below_ave5 ^ new.below_ave5) and old.rq != new.rq) \
#             or ((old.break_ave5 ^ new.break_ave5) and old.rq != new.rq) \
#             or ((old.break_ave10 ^ new.break_ave10) and old.rq != new.rq) \
#             or ((old.below_ave10 ^ new.below_ave10) and old.rq != new.rq):
#         new.prompt = True
#
#
# # 处理消息
# def deal_msg(monitor: Monitor, msg_dict) -> dict:
#     if (monitor.break_ave5 or monitor.below_ave5
#         or monitor.break_ave10 or monitor.below_ave10
#         or monitor.main_io_sell or monitor.main_io_buy) \
#             and monitor.prompt:
#         msg_dict[monitor.code] = {}
#         msg_dict[monitor.code]['编码'] = monitor.code
#         msg_dict[monitor.code]['名称'] = monitor.name
#         msg_dict[monitor.code]['最新价格'] = monitor.rt_price
#         msg_dict[monitor.code]['五日均线'] = monitor.ave5
#         msg_dict[monitor.code]['十日均线'] = monitor.ave10
#         if monitor.bs == 1:
#             msg_dict[monitor.code]['买卖'] = '买入'
#         if monitor.bs == 2:
#             msg_dict[monitor.code]['买卖'] = '卖出'
#         if monitor.break_ave5:
#             msg_dict[monitor.code]['提示1'] = '突破五日均线'
#         if monitor.break_ave10:
#             msg_dict[monitor.code]['提示2'] = '突破十日均线'
#         if monitor.below_ave5:
#             msg_dict[monitor.code]['提示3'] = '跌破五日均线'
#         if monitor.below_ave10:
#             msg_dict[monitor.code]['提示4'] = '跌破十日均线'
#         if monitor.main_io_sell:
#             msg_dict[monitor.code]['模式'] = monitor.main_io_sell_model
#             msg_dict[monitor.code]['提示5'] = '主力资金卖出'
#         if monitor.main_io_buy:
#             msg_dict[monitor.code]['模式'] = monitor.main_io_buy_model
#             msg_dict[monitor.code]['提示6'] = '主力资金买入'
#     return msg_dict
#
#
# def send_msg(msg_dict: dict):
#     u_info = user_info.selectone("whm")
#     prompt_code = u_info.get('prompt_code')
#     user_monitor_stock = stock_monitor.select_all(prompt_code)
#     msg = ''
#     for monitor_s in user_monitor_stock:
#         msg_info = msg_dict.get(monitor_s.get('code'))
#         if msg_info is None:
#             continue
#         if msg_info.get('买卖') == '卖出' and monitor_s.get('total_hand') == 0:
#             continue
#         for key in msg_info:
#             msg += key + ' : ' + str(msg_info[key]) + '\n'
#         msg += '\n'
#     # 处理消息
#     msg_util.miao_msg(prompt_code, msg)
#
#
# def test():
#     k_line = stock_day_k.select_rq_size('600970', '2021-08-17', 15)
#     form_info = form_util.get_best_form(form_util.parse_x_reverse(k_line, 'sp'))
#     print(form_info.__dict__)
#
#
# if __name__ == '__main__':
#     print('begin')
#     # monitor_one({'code': '601633', 'name': '长城汽车'})
#     # monitor_one({'code': '601995', 'name': '中金公司'})
#     # monitor_one({'code': '600585', 'name': '海螺水泥'})
#     # monitor_one({'code': '002389', 'name': '航天彩虹'})
#     # monitor_one({'code': '000858', 'name': '五粮液'})
#     # monitor_one({'code': '600031', 'name': '三一重工'})
#     # monitor_one({'code': '002466', 'name': '天齐锂业'})
#     # monitor_one({'code': '600036', 'name': '招商银行'})
#     # monitor_one({'code': '002709', 'name': '天赐材料'})
#     # monitor_one({'code': '600970', 'name': '中材国际'})
#     # monitor_one(Monitor("600111", "北方稀土"))
#     monitor_one(Monitor("000063", "中兴通讯"))
#     # monitor_one(Monitor("000157", "中联重科"))
#     # monitor_one(Monitor("600460", "士兰微"))
#     # monitor_one(Monitor("601995", "中金公司"))
#     # monitor_one(Monitor("002612", "航发动力"))
#     # monitor_task()
#     # start_task()
#     # send_msg({})
#     # test()
#     # m.ave5 = 100
